package org.rayken.trix.commons.game;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.rayken.trix.commons.card.Card;
import org.rayken.trix.commons.deck.Deck;
import org.rayken.trix.commons.deck.DeckFactory;

/**
 * A step in a Game
 * @author E-Kraiem-A
 *
 */

public abstract class Run {
	
	protected Game game;
	protected Deck deck;
	protected List<Trick> tricks = new ArrayList<Trick>();
	protected Player caller;
	protected Map<Player, List<Card>> deals = new HashMap<Player, List<Card>>();
	protected boolean forced;

	protected Run(Game game, Player caller, boolean forced) {
		super();
		this.game = game;
		this.caller = caller;
		this.forced = forced;
		deal();
	}
	
	private void deal(){
		deck = DeckFactory.createDeck();
		deck.shuffle();
		
		for(Player player : game.getPlayers()){
			deals.put(player, deck.extract(8));
		}
	}

	public Game getGame() {
		return game;
	}

	public Deck getDeck() {
		return deck;
	}

	public List<Trick> getTricks() {
		return tricks;
	}

	public Player getCaller() {
		return caller;
	}

	public Map<Player, List<Card>> getDeals() {
		return deals;
	}

	public void addScore(Player player, int scoreToAdd){
		game.addScore(player, scoreToAdd);
	}

	public boolean isForced() {
		return forced;
	}

	public Trick nextTrick() {
		Trick turn = new Trick(this);
		tricks.add(turn);
		return turn;
	}
	
	public Trick getLastPlayedTrick(){
		return tricks.get(tricks.size() - 1);
	}
	
	public boolean isComplete(){
		return tricks.size() == 8 && getLastPlayedTrick().isComplete();
	}
	
	
	
	public abstract boolean isFinished();
	public abstract RunType getType();
	public abstract void cardPlayed(Player player, Trick turn, Card cardToPlay);

	public abstract List<Card> getAvailablePlayableCard(Player player, Trick trick);
	
	protected List<Card> getAvailablePlayableCardDefault(Player player, Trick trick){
		List<Card> cardsInHand = deals.get(player);
		if (trick.getPlays().size() == 1)//we are at the first play
			return cardsInHand;
		
		Card firstCardPlayed = trick.getPlays().get(0).getCard();
		List<Card> playableCards = new ArrayList<Card>(8);
		for(Card card : cardsInHand) {
			if (card.getSuit() == firstCardPlayed.getSuit())
				playableCards.add(card);
		}
		if (playableCards.size() > 0)
			return playableCards;
		return cardsInHand;
	}
	
	
}





















